home *** CD-ROM | disk | FTP | other *** search
/ CU Amiga Super CD-ROM 14 / CU Amiga Magazine's Super CD-ROM 14 (1997)(EMAP Images)(GB)(Track 1 of 3)[!][issue 1997-09].iso / CUCD / Programming / RKMLibsPrgs / intuition / mouse_keyboard / rawkey.c < prev   
C/C++ Source or Header  |  1992-09-03  |  9KB  |  232 lines

  1. ;/* rawkey.c - Execute me to compile me with SAS C 5.10
  2. LC -b1 -cfistq -v -y -j73 rawkey.c
  3. Blink FROM LIB:c.o,rawkey.o TO rawkey LIBRARY LIB:LC.lib,LIB:Amiga.lib
  4. quit
  5. */
  6.  
  7. /*
  8. Copyright (c) 1992 Commodore-Amiga, Inc.
  9.  
  10. This example is provided in electronic form by Commodore-Amiga, Inc. for
  11. use with the "Amiga ROM Kernel Reference Manual: Libraries", 3rd Edition,
  12. published by Addison-Wesley (ISBN 0-201-56774-1).
  13.  
  14. The "Amiga ROM Kernel Reference Manual: Libraries" contains additional
  15. information on the correct usage of the techniques and operating system
  16. functions presented in these examples.  The source and executable code
  17. of these examples may only be distributed in free electronic form, via
  18. bulletin board or as part of a fully non-commercial and freely
  19. redistributable diskette.  Both the source and executable code (including
  20. comments) must be included, without modification, in any copy.  This
  21. example may not be published in printed form or distributed with any
  22. commercial product.  However, the programming techniques and support
  23. routines set forth in these examples may be used in the development
  24. of original executable software products for Commodore Amiga computers.
  25.  
  26. All other rights reserved.
  27.  
  28. This example is provided "as-is" and is subject to change; no
  29. warranties are made.  All use is at your own risk. No liability or
  30. responsibility is assumed.
  31. */
  32.  
  33. /*
  34. ** rawkey.c - How to correctly convert from RAWKEY to keymapped ASCII
  35. */
  36. #define INTUI_V36_NAMES_ONLY
  37.  
  38. #include <exec/types.h>
  39. #include <exec/memory.h>
  40. #include <intuition/intuition.h>
  41. #include <devices/inputevent.h>
  42. #include <clib/exec_protos.h>
  43. #include <clib/intuition_protos.h>
  44. #include <clib/console_protos.h>
  45. #include <stdio.h>
  46.  
  47. #ifdef LATTICE
  48. int CXBRK(void)    { return(0); }  /* Disable Lattice CTRL/C handling */
  49. int chkabort(void) { return(0); }  /* really */
  50. #endif
  51.  
  52. /* our function prototypes */
  53. LONG deadKeyConvert(struct IntuiMessage *msg, UBYTE *kbuffer,
  54.                     LONG kbsize, struct KeyMap *kmap, struct InputEvent *ievent);
  55. VOID print_qualifiers(ULONG qual);
  56. BOOL doKeys(struct IntuiMessage *msg, struct InputEvent *ievent,
  57.                     UBYTE **buffer, ULONG *bufsize);
  58. VOID process_window(struct Window *win, struct InputEvent *ievent,
  59.                     UBYTE **buffer, ULONG *bufsize);
  60.  
  61. /* A buffer is created for RawKeyConvert() to put its output. BUFSIZE is the size of
  62. ** the buffer in bytes.  NOTE that this program starts out with a buffer size of 2.
  63. ** This is only to show how the buffer is automatically increased in size  by this
  64. ** example!  In an application, start with a much larger buffer and you will probably
  65. ** never have to increase its size. 128 bytes or so should do the trick, but always
  66. ** be able to change the size if required.
  67. */
  68. #define BUFSIZE (2)
  69.  
  70. struct Library *IntuitionBase, *ConsoleDevice;
  71.  
  72. /* main() - set-up everything used by program. */
  73. VOID main(int argc, char **argv)
  74. {
  75. struct Window *win;
  76. struct IOStdReq ioreq;
  77. struct InputEvent *ievent;
  78. UBYTE *buffer;
  79. ULONG bufsize = BUFSIZE;
  80.  
  81. if(IntuitionBase = OpenLibrary("intuition.library",37)) {
  82.     /* Open the console device just to do keymapping. (unit -1 means any unit) */
  83.     if (0 == OpenDevice("console.device",-1,(struct IORequest *)&ioreq,0)) {
  84.         ConsoleDevice = (struct Library *)ioreq.io_Device;
  85.  
  86.         /* Allocate the initial character buffer used by deadKeyConvert() and RawKeyConvert()
  87.         ** for returning translated characters. If the characters generated by these routines
  88.         ** cannot fit into the buffer, the application must pass a larger buffer.  This is
  89.         ** done in this code by freeing the old buffer and allocating a new one.
  90.         */
  91.         if (buffer = AllocMem(bufsize,MEMF_CLEAR)) {
  92.             if (ievent = AllocMem(sizeof(struct InputEvent),MEMF_CLEAR)) {
  93.                 if (win = OpenWindowTags(NULL,
  94.                         WA_Width, 300,
  95.                         WA_Height, 50,
  96.                         WA_Flags, WFLG_DEPTHGADGET | WFLG_CLOSEGADGET | WFLG_ACTIVATE,
  97.                         WA_IDCMP, IDCMP_CLOSEWINDOW | IDCMP_RAWKEY,
  98.                         WA_Title, "Raw Key Example",
  99.                         TAG_END)) {
  100.                     printf("Press keyboard keys to see ASCII conversion from rawkey\n");
  101.                     printf("Unprintable characters will be shown as %c\n\n",0x7f);
  102.                     process_window(win,ievent,&buffer,&bufsize);
  103.                     CloseWindow(win);
  104.                     }
  105.                 FreeMem(ievent,sizeof(struct InputEvent));
  106.                 }
  107.             /* Buffer can be freed elsewhere in the program so test first. */
  108.             if (buffer != NULL)
  109.                 FreeMem(buffer,bufsize);
  110.             }
  111.         CloseDevice((struct IORequest *)&ioreq);
  112.         }
  113.     CloseLibrary(IntuitionBase);
  114.     }
  115. }
  116.  
  117. /* Convert RAWKEYs into VANILLAKEYs, also shows special keys like HELP, Cursor Keys,
  118. ** FKeys, etc.  It returns:
  119. **   -2 if not a RAWKEY event.
  120. **   -1 if not enough room in the buffer, try again with a bigger buffer.
  121. **   otherwise, returns the number of characters placed in the buffer.
  122. */
  123. LONG deadKeyConvert(struct IntuiMessage *msg, UBYTE *kbuffer,
  124.     LONG kbsize, struct KeyMap *kmap, struct InputEvent *ievent)
  125. {
  126. if (msg->Class != IDCMP_RAWKEY) return(-2);
  127. ievent->ie_Class = IECLASS_RAWKEY;
  128. ievent->ie_Code = msg->Code;
  129. ievent->ie_Qualifier = msg->Qualifier;
  130. ievent->ie_position.ie_addr = *((APTR*)msg->IAddress);
  131.  
  132. return(RawKeyConvert(ievent,kbuffer,kbsize,kmap));
  133. }
  134.  
  135. /* print_qualifiers() - print out the values found in the qualifier bits of
  136. ** the message. This will print out all of the qualifier bits set.
  137. */
  138. VOID print_qualifiers(ULONG qual)
  139. {
  140. printf("Qual:");
  141. if (qual & IEQUALIFIER_LSHIFT)         printf("LShft,");
  142. if (qual & IEQUALIFIER_RSHIFT)         printf("RShft,");
  143. if (qual & IEQUALIFIER_CAPSLOCK)       printf("CapLok,");
  144. if (qual & IEQUALIFIER_CONTROL)        printf("Ctrl,");
  145. if (qual & IEQUALIFIER_LALT)           printf("LAlt,");
  146. if (qual & IEQUALIFIER_RALT)           printf("RAlt,");
  147. if (qual & IEQUALIFIER_LCOMMAND)       printf("LCmd,");
  148. if (qual & IEQUALIFIER_RCOMMAND)       printf("RCmd,");
  149. if (qual & IEQUALIFIER_NUMERICPAD)     printf("NumPad,");
  150. if (qual & IEQUALIFIER_REPEAT)         printf("Rpt,");
  151. if (qual & IEQUALIFIER_INTERRUPT)      printf("Intrpt,");
  152. if (qual & IEQUALIFIER_MULTIBROADCAST) printf("Multi Broadcast,");
  153. if (qual & IEQUALIFIER_MIDBUTTON)      printf("MidBtn,");
  154. if (qual & IEQUALIFIER_RBUTTON)        printf("RBtn,");
  155. if (qual & IEQUALIFIER_LEFTBUTTON)     printf("LBtn,");
  156. if (qual & IEQUALIFIER_RELATIVEMOUSE)  printf("RelMouse,");
  157. }
  158.  
  159. /* doKeys() - Show what keys were pressed. */
  160. BOOL doKeys(struct IntuiMessage *msg, struct InputEvent *ievent,
  161.             UBYTE **buffer, ULONG *bufsize)
  162. {
  163. USHORT char_pos;
  164. USHORT numchars;
  165. BOOL   ret_code = TRUE;
  166. UBYTE  realc, c;
  167.  
  168. /* deadKeyConvert() returns -1 if there was not enough space in the buffer to
  169. ** convert the string. Here, the routine increases the size of the buffer on the
  170. ** fly...Set the return code to FALSE on failure.
  171. */
  172. numchars = deadKeyConvert(msg, *buffer, *bufsize - 1, NULL, ievent);
  173. while ((numchars == -1) && (*buffer != NULL)) {
  174.     /* conversion failed, buffer too small. try to double the size of the buffer. */
  175.     FreeMem(*buffer, *bufsize);
  176.     *bufsize = *bufsize << 1;
  177.     printf("Increasing buffer size to %d\n", *bufsize);
  178.  
  179.     if (NULL == (*buffer = AllocMem(*bufsize, MEMF_CLEAR)))  ret_code = FALSE;
  180.     else  numchars = deadKeyConvert(msg, *buffer, *bufsize - 1, NULL, ievent);
  181.     }
  182.  
  183. /* numchars contains the number of characters placed within the buffer.  Key up events and   */
  184. /* key sequences that do not generate any data for the program (like deadkeys) will return   */
  185. /* zero.  Special keys (like HELP, the cursor keys, FKeys, etc.) return multiple characters  */
  186. /* that have to then be parsed by the application.  Allocation failed above if buffer is NULL*/
  187. if (*buffer != NULL) {
  188.     /* if high bit set, then this is a key up otherwise this is a key down */
  189.     if (msg->Code & 0x80)
  190.           printf("Key Up:   ");
  191.     else
  192.           printf("Key Down: ");
  193.  
  194.     print_qualifiers(msg->Qualifier);
  195.     printf(" rawkey #%d maps to %d ASCII character(s)\n", 0x7F & msg->Code, numchars);
  196.     for (char_pos = 0; char_pos < numchars; char_pos++) {
  197.         realc = c = (*buffer)[char_pos];
  198.         if ((c <= 0x1F)||((c >= 0x80)&&(c < 0xa0)))
  199.             c = 0x7f;
  200.         printf("  %3d ($%02x) = %c\n", realc, realc, c);
  201.         }
  202.     }
  203. return(ret_code);
  204. }
  205.  
  206. /* process_window() - simple event loop.  Note that the message is not replied
  207. ** to until the end of the loop so that it may be used in the doKeys() call.
  208. */
  209. VOID process_window(struct Window *win, struct InputEvent *ievent,
  210.     UBYTE **buffer, ULONG *bufsize)
  211. {
  212. struct IntuiMessage *msg;
  213. BOOL done;
  214.  
  215. done = FALSE;
  216. while (done == FALSE) {
  217.     Wait((1L<<win->UserPort->mp_SigBit));
  218.     while ((done == FALSE) && (msg = (struct IntuiMessage *)GetMsg(win->UserPort))) {
  219.         switch (msg->Class) {     /* handle our events */
  220.             case IDCMP_CLOSEWINDOW:
  221.                 done = TRUE;
  222.                 break;
  223.             case IDCMP_RAWKEY:
  224.                 if (FALSE == doKeys(msg,ievent,buffer,bufsize))
  225.                     done = TRUE;
  226.                 break;
  227.             }
  228.         ReplyMsg((struct Message *)msg);
  229.         }
  230.     }
  231. }
  232.